package com.eonmind.ai.controller;

import com.eonmind.ai.dto.AiChatDto;
import com.eonmind.ai.service.impl.AiAssistantService;
import com.eonmind.ai.service.impl.AiConversationService;
import com.eonmind.ai.service.impl.AiModelCategoryService;
import com.eonmind.ai.service.impl.AiModelService;
import com.eonmind.common.contract.data.response.PageResponse;
import com.eonmind.common.contract.data.response.ResponseEntity;
import com.eonmind.common.contract.enums.oss.OssBucketEnum;
import com.eonmind.common.contract.oss.OssUtil;
import com.eonmind.common.contract.oss.dto.OssDto;
import com.eonmind.common.security.annotations.UserInfo;
import com.eonmind.user.contract.dto.UserInfoData;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.text.MessageFormat;
import java.util.List;

import static com.eonmind.common.contract.constants.ai.AiConstant.AI_CHAT_TEMP_FILE_PATH;

/**
 * AI聊天会话
 */
@RestController
public class AiChatController {

    @Resource
    private AiConversationService aiConversationService;

    @Resource
    private AiModelService aiModelService;

    @Resource
    private AiAssistantService aiAssistantService;
    @Autowired
    private OssUtil ossUtil;
    @Autowired
    private AiModelCategoryService aiModelCategoryService;


    /**
     * 获取用户临时访问凭证
     *
     * @param userInfoData
     * @return
     * @ignoreParams userInfoData
     */
    @UserInfo
    @PostMapping("/ai/user/sts")
    public ResponseEntity<OssDto.StsResponse> userStsToken(UserInfoData userInfoData) {
        String filePath = MessageFormat.format(AI_CHAT_TEMP_FILE_PATH, userInfoData.getId());
        OssDto.StsResponse stsResponse = ossUtil.GetAccessCredentials(OssBucketEnum.KNOWLEDGE_BUCKET, filePath);
        return ResponseEntity.success(stsResponse);

    }

    /**
     * 分页查询会话
     *
     * @param pageRequest 请求参数
     * @return
     * @ignoreParams userInfoData
     */
    @UserInfo
    @PostMapping("/ai/conversation/page")

    public ResponseEntity<PageResponse<AiChatDto.AiConversationData>> pageConversation(UserInfoData userInfoData, @RequestBody AiChatDto.AiConversationPageRequest pageRequest) {
        return ResponseEntity.success(aiConversationService.pageConversation(userInfoData, pageRequest));
    }

    /**
     * 创建会话
     *
     * @param createRequest 请求参数
     * @return
     * @ignoreParams userInfoData
     */
    @UserInfo
    @PostMapping("/ai/conversation/create")
    public ResponseEntity<AiChatDto.AiConversationData> createConversation(UserInfoData userInfoData, @RequestBody AiChatDto.AiConversationCreateRequest createRequest) {
        AiChatDto.AiConversationData conversation = aiConversationService.createConversation(userInfoData, createRequest);
        return ResponseEntity.success(conversation);
    }

    /**
     * 重命名会话
     *
     * @param editRequest 请求参数
     * @return
     * @ignoreParams userInfoData
     */
    @UserInfo
    @PostMapping("/ai/conversation/edit")
    public ResponseEntity<?> createConversation(UserInfoData userInfoData, @RequestBody AiChatDto.AiConversationEditRequest editRequest) {
        aiConversationService.editConversation(userInfoData, editRequest);
        return ResponseEntity.success();
    }


    /**
     * 删除对话记录
     *
     * @param delRequest 删除对话的请求对象，包含删除对话所需的信息
     * @return
     * @ignoreParams userInfoData
     */
    @UserInfo
    @PostMapping("/ai/conversation/del")
    public ResponseEntity<?> delConversation(UserInfoData userInfoData, @RequestBody AiChatDto.AiConversationDelRequest delRequest) {
        aiConversationService.delConversation(userInfoData, delRequest);
        return ResponseEntity.success();
    }


    /**
     * 获取所有模型列表
     *
     * @return
     */
    @GetMapping("/ai/model/list")
    public ResponseEntity<List<AiChatDto.AiModelData>> listModels(@RequestParam(name = "keyword", required = false) String keyword) {
        return ResponseEntity.success(aiModelService.listModelByKeyword(keyword));
    }

    /**
     * 获取所有模型分类列表
     *
     * @return
     */
    @PostMapping("/ai/model/category/list")
    public ResponseEntity<List<AiChatDto.AiModelCategoryData>> listModelCategory() {
        return ResponseEntity.success(aiModelCategoryService.listModelCategory());
    }

    /**
     * 获取模型分类下的模型列表
     *
     * @param request 请求参数
     * @return
     */
    @PostMapping("/ai/model/category/model/list")
    public ResponseEntity<List<AiChatDto.AiModelData>> listCategoryModel(@RequestBody @Validated AiChatDto.AiModelCategoryListRequest request) {
        return ResponseEntity.success(aiModelCategoryService.listCategoryModels(request));
    }


    /**
     * 获取会话消息列表
     *
     * @param conversationId 会话ID
     * @return
     * @ignoreParams userInfoData
     */
    @UserInfo
    @GetMapping("/ai/conversation/message")
    public ResponseEntity<List<AiChatDto.AiConversationMessageData>>
    listConversationMessages(UserInfoData userInfoData, @RequestParam(name = "conversationId", required = true) Long conversationId) {
        return ResponseEntity.success(aiConversationService.listConversationMessages(userInfoData, conversationId));
    }

    /**
     * 聊天
     *
     * @param aiChatRequest 聊天请求参数
     * @return
     * @ignoreParams userInfoData
     * @ignoreParams httpServletResponse
     */
    @UserInfo
    @PostMapping(value = "/ai/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ResponseEntity<AiChatDto.AiChatData>> chat(
            UserInfoData userInfoData
            , HttpServletResponse httpServletResponse
            , @RequestBody @Validated AiChatDto.AiChatRequest aiChatRequest) {
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setHeader("Connection", "keep-alive");
        return aiConversationService.chat(userInfoData.getId(), aiChatRequest);
    }

    /**
     * 获取Assistant助手列表
     *
     * @param keyword 关键字，选传
     * @return
     * @ignoreParams userInfoData
     */
    @GetMapping("/ai/assistant/list")
    public ResponseEntity<List<AiChatDto.AiAssistantData>> listAssistant(UserInfoData userInfoData
            , @RequestParam(name = "keyword", required = false) String keyword) {
        return ResponseEntity.success(aiAssistantService.listAssistant(keyword));
    }
}
